package com.srmt.document.feishu.internal.table;

import com.lark.oapi.service.docx.v1.model.Block;
import com.lark.oapi.service.docx.v1.model.TableMergeInfo;
import com.lark.oapi.service.docx.v1.model.UpdateBlockRequest;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.core.BlockContext;
import com.srmt.document.feishu.internal.table.model.TableContext;
import com.srmt.document.feishu.internal.table.model.TableType;
import com.srmt.document.model.ColumnData;
import com.srmt.document.model.RowData;
import com.srmt.document.model.TableData;

import java.util.List;
import java.util.Map;

/**
 * 表格操作策略接口
 * 
 * 定义不同类型表格（如普通表格、多维表格）的操作接口。
 * 每种表格类型应该实现此接口，提供特定于该类型的操作逻辑。
 * 
 * @author srmt
 * @since 3.0.0
 */
public interface TableOperationStrategy {
    
    /**
     * 获取策略支持的表格类型
     * 
     * @return 表格类型
     */
    TableType getTableType();
    
    /**
     * 判断是否支持指定的Block类型
     * 
     * @param blockType Block类型编号
     * @return 是否支持
     */
    boolean supportsBlockType(int blockType);
    
    // ========== 表格创建操作 ==========
    
    /**
     * 创建表格结构
     * 
     * @param rows 行数
     * @param cols 列数
     * @param content 表格内容（可选）
     * @return Block数组，包含表格Block和所有子Block
     * @throws TableException 如果创建失败
     */
    Block[] createTableStructure(int rows, int cols, List<List<String>> content) 
            throws TableException;
    
    // ========== 表格定位操作 ==========
    
    /**
     * 定位表格中的特定单元格
     * 
     * @param context 表格上下文
     * @param row 行索引（从0开始）
     * @param col 列索引（从0开始）
     * @return 单元格Block ID
     * @throws TableException 如果无法定位单元格
     */
    String locateTableCell(TableContext context, int row, int col) 
            throws TableException;
    
    /**
     * 查找包含指定文本的单元格位置
     * 
     * @param context 表格上下文
     * @param text 要查找的文本
     * @return 单元格位置[row, col]，如果未找到返回null
     * @throws TableException 如果查找失败
     */
    int[] findCellWithText(TableContext context, String text) 
            throws TableException;
    
    // ========== 表格内容操作 ==========
    
    /**
     * 更新单元格内容（基于行列索引）
     * 
     * @param context 表格上下文
     * @param row 行索引（从1开始）
     * @param col 列索引（从1开始）
     * @param value 新的单元格内容
     * @throws TableException 如果更新失败
     */
    void updateCellContentByIndex(TableContext context, int row, int col, String value) 
            throws TableException;
    
    /**
     * 批量更新单元格内容（基于行列索引）
     * 
     * @param context 表格上下文
     * @param cellUpdates 单元格更新映射 ([row, col] -> value)
     * @throws TableException 如果更新失败
     */
    void batchUpdateCellsByIndex(TableContext context, Map<int[], String> cellUpdates) 
            throws TableException;
    
    /**
     * 获取单元格内容
     * 
     * @param context 表格上下文
     * @param row 行索引 >1
     * @param col 列索引 >1
     * @return 单元格文本内容
     * @throws TableException 如果获取失败
     */
    String getCellContent(TableContext context, int row, int col) 
            throws TableException;
    
    // ========== 表格结构操作 ==========
    
    /**
     * 获取表格维度信息
     * 
     * @param context 表格上下文
     * @return [行数, 列数]数组
     * @throws TableException 如果获取失败
     */
    int[] getTableDimensions(TableContext context) 
            throws TableException;
    
    /**
     * 获取表格合并信息
     * 
     * @param context 表格上下文
     * @return 合并信息数组，如果没有合并返回null
     * @throws TableException 如果获取失败
     */
    TableMergeInfo[] getTableMergeInfo(TableContext context) 
            throws TableException;
    
    /**
     * 判断指定单元格是否被合并
     * 
     * @param context 表格上下文
     * @param row 行索引
     * @param col 列索引
     * @return 如果被合并返回true
     * @throws TableException 如果判断失败
     */
    boolean isMergedCell(TableContext context, int row, int col) 
            throws TableException;
    
    /**
     * 获取合并单元格的跨度
     * 
     * @param context 表格上下文
     * @param row 行索引
     * @param col 列索引
     * @return [rowSpan, colSpan]数组
     * @throws TableException 如果获取失败
     */
    int[] getCellSpan(TableContext context, int row, int col) 
            throws TableException;
    
    // ========== 表格数据转换 ==========
    
    /**
     * 将表格Block转换为TableData对象
     * 
     * @param context 表格上下文
     * @return TableData对象
     * @throws TableException 如果转换失败
     */
    TableData convertToTableData(TableContext context) 
            throws TableException;
    
    /**
     * 从Block构建TableData
     * 
     * @param tableBlock 表格Block
     * @param blockMap Block ID到Block的映射
     * @return TableData对象
     * @throws TableException 如果构建失败
     */
    TableData buildTableFromBlocks(Block tableBlock, Map<String, Block> blockMap) 
            throws TableException;
    
    // ========== 表格行列操作 ==========
    
    /**
     * 添加表格行
     * 
     * @param context 表格上下文
     * @param rows 要添加的行数据
     * @param position 插入位置（-1表示末尾）
     * @throws TableException 如果添加失败
     */
    void addTableRows(TableContext context, List<RowData> rows, int position) 
            throws TableException;
    
    /**
     * 删除表格行
     * 
     * @param context 表格上下文
     * @param startRow 起始行索引 >=1
     * @param endRow 结束行索引（包含） >=1
     * @throws TableException 如果删除失败
     */
    void deleteTableRows(TableContext context, int startRow, int endRow) 
            throws TableException;
    
    /**
     * 添加表格列
     * 
     * @param context 表格上下文
     * @param columns 要添加的列数据
     * @param position 插入位置（-1表示末尾）
     * @throws TableException 如果添加失败
     */
    void addTableColumns(TableContext context, List<ColumnData> columns, int position) 
            throws TableException;
    
    /**
     * 删除表格列
     * 
     * @param context 表格上下文
     * @param startCol 起始列索引 >=1
     * @param endCol 结束列索引（包含）>=1
     * @throws TableException 如果删除失败
     */
    void deleteTableColumns(TableContext context, int startCol, int endCol) 
            throws TableException;
    
    // ========== 单元格合并操作 ==========
    
    /**
     * 合并单元格
     * 
     * @param context 表格上下文
     * @param startRow 起始行索引
     * @param startCol 起始列索引
     * @param endRow 结束行索引（包含）
     * @param endCol 结束列索引（包含）
     * @throws TableException 如果合并失败
     */
    void mergeCells(TableContext context, int startRow, int startCol, 
                   int endRow, int endCol) throws TableException;
    
    /**
     * 取消合并单元格
     * 
     * @param context 表格上下文
     * @param startRow 起始行索引
     * @param startCol 起始列索引
     * @param endRow 结束行索引（包含）
     * @param endCol 结束列索引（包含）
     * @throws TableException 如果取消合并失败
     */
    void unmergeCells(TableContext context, int startRow, int startCol,
                     int endRow, int endCol) throws TableException;
    
    // ========== 工具方法 ==========
    
    /**
     * 验证表格操作是否有效
     * 
     * @param context 表格上下文
     * @return 是否有效
     */
    boolean validateTableOperation(TableContext context);
    
    /**
     * 获取策略的描述信息
     * 
     * @return 策略描述
     */
    String getDescription();
}